// File Name: flash_logic.c
// Author: kukukukuku~
// Date: 2024-07-12

#include "./User/Flash/inc/flash_logic.h"
#include "./User/Key/inc/key_ctrl.h"
#include "./User/LED/inc/led_logic.h"
#include "./User/OLED/inc/oled_ctrl.h"
#include "./User/Step_Motor/inc/step_motor_logic.h"
#include "./User/WS2812B/inc/ws2812b_ctrl.h"
#include "string.h"

/**
 * @brief   保存数据
 * @param   flashAddrStart: 起始地址
 * @param   data:           数据源
 * @param   dataLen:        数据个数
 * @retval  保存结果
 * - 0:     保存成功
 * - 1:     擦除失败
 * - 2:     保存失败
 * @note    None
*/
uint8_t flash_data_save(const uint32_t flashAddrStart, const uint16_t * const data, uint16_t dataLen)
{
    flash_unlock();
    if(flash_erase_sectors(FLASH_ADDR_DATA_START))
    {
        flash_lock();
        return 1;
    }
    
    //保存前缀
    if(flash_program_data_halfword(flashAddrStart, 0x1112))
    {
        flash_lock();
        return 2;
    }
    
    //保存数据个数
    if(flash_program_data_halfword(flashAddrStart + 2, dataLen))
    {
        flash_lock();
        return 2;
    }
    
    //保存数据
    for(uint8_t i = 0; i < dataLen; i++)
    {
        if(flash_program_data_halfword(flashAddrStart + (i + 2) * 2, data[i]))
        {
            flash_lock();
            return 2;
        }
    }
    
    flash_lock();
    return 0;
}


/**
 * @brief   读取数据
 * @param   None
 * @retval  读取结果
 * - 0:     读取成功
 * - 1:     读取失败
 * @note    None
*/
uint8_t flash_read(void)
{
    if(*(volatile uint16_t *)FLASH_ADDR_DATA_START == 0x1112 && *(volatile uint16_t *)(FLASH_ADDR_DATA_START + 2) == FLASH_DATA_NUM)
    {
        memcpy(flashData, (uint16_t *)(FLASH_ADDR_DATA_START + 4), sizeof(flashData));
        
        keyClickBeep    = flashData[FLASH_DATA_KEY_CLICK_BEEP_INDEX];
        keyLongBeep     = flashData[FLASH_DATA_KEY_LONG_BEEP_INDEX];
        led1.mode       = !!(uint8_t)flashData[FLASH_DATA_LED1_MODE_INDEX];
        led1.blinkNum   = flashData[FLASH_DATA_LED1_BLINK_FREQ_INDEX];
        led1.breathStep = flashData[FLASH_DATA_LED1_BREATH_STEP_INDEX];
        led2.mode       = !!(uint8_t)flashData[FLASH_DATA_LED2_MODE_INDEX];
        led2.blinkNum   = flashData[FLASH_DATA_LED2_BLINK_FREQ_INDEX];
        led2.breathStep = flashData[FLASH_DATA_LED2_BREATH_STEP_INDEX];
        oledDir         = (uint8_t)flashData[FLASH_DATA_OLED_DIR_INDEX];
        oledLightLevel  = (uint8_t)flashData[FLASH_DATA_OLED_LIGHT_INDEX];
        stepMotorMode   = (StepMotorMode)flashData[FLASH_DATA_STEP_MOTOR_MODE_INDEX];
        stepMotorSpd    = (uint8_t)flashData[FLASH_DATA_STEP_MOTOR_SPEED_INDEX];
        ws2812bCwMode   = (uint8_t)flashData[FLASH_DATA_WS2812B_CW_MODE_INDEX];
        ws2812bCwRed    = (uint8_t)flashData[FLASH_DATA_WS2812B_CW_R_INDEX];
        ws2812bCwGreen  = (uint8_t)flashData[FLASH_DATA_WS2812B_CW_G_INDEX];
        ws2812bCwBlue   = (uint8_t)flashData[FLASH_DATA_WS2812B_CW_B_INDEX];
        ws2812bCcwMode  = (uint8_t)flashData[FLASH_DATA_WS2812B_CCW_MODE_INDEX];
        ws2812bCcwRed   = (uint8_t)flashData[FLASH_DATA_WS2812B_CCW_R_INDEX];
        ws2812bCcwGreen = (uint8_t)flashData[FLASH_DATA_WS2812B_CCW_G_INDEX];
        ws2812bCcwBlue  = (uint8_t)flashData[FLASH_DATA_WS2812B_CCW_B_INDEX];
        
        led_set_mode(&led1, led1.mode);
        led_set_blink_time(&led1, led1.blinkNum);
        led_set_breath_step(&led1, led1.breathStep);
        led_set_mode(&led2, led2.mode);
        led_set_blink_time(&led2, led2.blinkNum);
        led_set_breath_step(&led2, led2.breathStep);
        
        step_motor_set_mode(stepMotorMode);
        step_motor_set_rotate_speed(stepMotorSpd);
        
        return 0;
    }
    
    return 1;
}
